/*
 * 学期编辑左侧课程列表
 * 
 * Notes: 选中某个课程动态加载此课程所有课时Lessons并展开
 * 同时关闭其他打开的菜单
 */
import * as React from 'react';
import { connect } from 'react-redux';
import { get } from 'lodash';

import { isLoading, isEqualWithNumber } from 'utils/utils';
import ACTIONS from 'constants/course';
import ACTIONS_LESSON from 'constants/lesson';

import { fetchCourseLessons } from 'actions/lesson';
import { fetchCourseList, sortCourseLessons } from 'actions/course';

import LoadableComponent from 'components/common/LoadableComponent';
const LoadablePopToSort = LoadableComponent(() => import('components/common/PopToSort'));

import { Icon, Menu, message, Tooltip, Spin, Badge } from 'antd';
import './List.scss';

interface CourseListProps {
  dispatch: (action: any) => any;
  handleEditCourse: (action: any) => void;
  handleEditLesson: (data: any) => void;
  courseList: any[];
  lessonList: any[];
  loadingGroup: any;
}

interface CourseListState {
  openKeys: any;
  selectedKeys: any;
  sortLessonOfCourseId: number;
}

class List extends React.Component<CourseListProps, CourseListState> {
  static defaultProps: CourseListProps = {
    dispatch: () => {},
    handleEditCourse: () => {},
    handleEditLesson: () => {},
    courseList: [],
    lessonList: [],
    loadingGroup: {},
  };
  constructor(props: CourseListProps) {
    super(props);

    this.state = {
      openKeys: [],
      selectedKeys: [],
      sortLessonOfCourseId: 0,
    };
  }

  componentDidMount() {
    this.props.dispatch(fetchCourseList());
  }

  handleAddLesson = (course: any, lessonId: number = 0) => {
    const { id: courseId, level } = course;
    const { handleEditLesson } = this.props;
    const courseName = `Level ${level}`;
    this.setState({
      selectedKeys: [courseId + '_' + lessonId],
    });
    handleEditLesson({ courseId, courseName, lessonId });
  };

  handleFetchLessons = (openCourseId: number = this.state.openKeys[0]) => {
    this.props.dispatch(fetchCourseLessons(openCourseId));
  };

  // 打开课程
  handleMenuOpen = (openKeys: any) => {
    this.setState(
      {
        openKeys: openKeys.filter((openKey: any) => {
          return this.state.openKeys.indexOf(openKey) === -1;
        }),
      },
      () => {
        if (this.state.openKeys.length > 0) {
          this.handleFetchLessons();
        }
      }
    );
  };

  // 选中课程下面的课时
  handleMenuItemSelect = (item: any) => {
    const { courseList } = this.props;
    const [courseId, lessonId] = item['key'].split('_');

    const course = courseList.find((item: any) => {
      return isEqualWithNumber(item.id, courseId);
    });

    this.handleAddLesson(course, lessonId);
    this.setState({
      selectedKeys: [item['key']],
    });
  };

  renderSubMenu = (item: any) => {
    let { lessonList, loadingGroup } = this.props;
    const courseId = item.id;
    const [openCourseId] = this.state.openKeys;

    let itemRenderHtml: any = [],
      operationButtons: any[] = [];

    const itemTitle = (
      <span>
        <Icon type="folder-open" />
        &nbsp; Lessons
      </span>
    );

    const publishMap = [
      {
        color: '#f5222d',
        title: '课时未发布',
      },
      {
        color: '#52c41a',
        title: '课时已发布',
      },
      {
        color: '#faad14',
        title: '课时已改动，请重新发布！',
      },
    ];

    // 当前打开的课程
    const isSameCourse = isEqualWithNumber(courseId, openCourseId);
    if (isSameCourse) {
      itemRenderHtml = lessonList.map((lesson: any, index: number) => {
        const { color, title } = publishMap[Number(lesson.isPublished)];
        const badgeStyle = {
          backgroundColor: color,
        };
        const tipTitle = title;
        return (
          <Menu.Item key={`${courseId}_${lesson.id}`} className="lesson-item">
            <div className="item-wrap">
              <Tooltip title={tipTitle}>
                <Badge style={badgeStyle} count={index + 1} />
                &nbsp;&nbsp;
                {lesson.name}
              </Tooltip>
              {index === 0 && (
                <Tooltip overlay="默认第一个课时是体验课">
                  <span style={{ color: '#2db7f5', position: 'absolute', right: 2 }}>
                    <Icon type="eye" />
                  </span>
                </Tooltip>
              )}
            </div>
          </Menu.Item>
        );
      });
    }

    operationButtons = [
      <Tooltip overlay="添加课时" key="add lesson">
        <a
          href="javascript:void(0);"
          className="operation-button"
          onClick={() => {
            this.handleAddLesson(item, 0);
          }}>
          <Icon type="plus" />
        </a>
      </Tooltip>,
    ];

    if (lessonList.length > 1) {
      operationButtons.push(
        <Tooltip overlay="课时排序" key="sort lesson">
          <a
            href="javascript:void(0);"
            className="operation-button"
            onClick={() => {
              this.handleSortLesson(courseId);
            }}>
            <Icon type="bars" />
          </a>
        </Tooltip>
      );
    }

    const isCoursePublished = get(item, 'isPublished', 0);

    return (
      <Menu.SubMenu
        key={courseId}
        title={
          <div>
            <Tooltip key="publish" title={isCoursePublished ? '课程已发布' : '课程未发布'}>
              <Badge status={isCoursePublished ? 'success' : 'default'} />
              <span className="course-name">Level {item.level}</span>
              &nbsp;&nbsp;
            </Tooltip>
            <Tooltip key="edit" title="编辑课程">
              <Icon
                type="edit"
                className="course-edit"
                onClick={event => {
                  event.stopPropagation();
                  this.props.handleEditCourse(item);
                }}
              />
            </Tooltip>
            <br />
            <p className="course-description">{item['description']}</p>
          </div>
        }>
        {isSameCourse && (
          <Menu.ItemGroup
            disabled={false}
            title={
              <Spin spinning={isLoading(loadingGroup, ACTIONS_LESSON.FETCH_LIST)}>
                <div className="lesson-operation-section">
                  {itemTitle}
                  {operationButtons}
                  <div className="clear-both" />
                </div>
              </Spin>
            }>
            {itemRenderHtml}
          </Menu.ItemGroup>
        )}
      </Menu.SubMenu>
    );
  };

  handleSortCancel = () => {
    this.setState({
      sortLessonOfCourseId: 0,
    });
  };

  handleSortLesson = (courseId: number) => {
    this.setState({
      sortLessonOfCourseId: courseId,
    });
  };

  handleSortOk = (sortedIds: number[]) => {
    const { dispatch } = this.props;
    const { sortLessonOfCourseId } = this.state;

    dispatch(sortCourseLessons(sortLessonOfCourseId, sortedIds)).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        this.handleFetchLessons(sortLessonOfCourseId);
        this.setState({
          sortLessonOfCourseId: 0,
        });
        message.success('保存成功');
      }
    });
  };

  render() {
    const { selectedKeys, sortLessonOfCourseId } = this.state;
    const { courseList, loadingGroup, lessonList } = this.props;

    let menuItems = null;
    if (courseList.length > 0) {
      menuItems = (
        <Menu
          id="lesson_list"
          mode="inline"
          onOpenChange={this.handleMenuOpen}
          openKeys={this.state.openKeys}
          selectedKeys={selectedKeys}
          onSelect={this.handleMenuItemSelect}>
          {courseList.map(this.renderSubMenu)}
        </Menu>
      );
    } else {
      menuItems = (
        <p className="loading-placeholder">
          <Icon type="frown-o" />
          &nbsp; 课程为空
        </p>
      );
    }

    return (
      <React.Fragment>
        {sortLessonOfCourseId > 0 && (
          <LoadablePopToSort
            sortName="课时排序"
            items={lessonList}
            onCancel={this.handleSortCancel}
            onOk={this.handleSortOk}
          />
        )}
        <Spin spinning={isLoading(loadingGroup, ACTIONS.FETCH_LIST)}>{menuItems}</Spin>
      </React.Fragment>
    );
  }
}

function mapStateToProps(state: any) {
  const { loadingGroup } = state;
  const { courseList } = state.course;
  const { lessonList } = state.lesson;

  return {
    loadingGroup,
    courseList,
    lessonList,
  };
}

export default connect(mapStateToProps)(List);
